package com.neoCalf.neoGateway.config;

import com.neoCalf.neoGateway.filter.AuthenticationFilter;
import com.neoCalf.neoGateway.properties.AppContext;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.reactive.function.client.WebClient;

import javax.annotation.Resource;

/**
 * @author 小牛
 * @version 1.0
 * @description TODO
 * @date 2025/4/7 23:06
 */
@Configuration
public class GatewayConfig {
    @Resource
    private AppContext appContext;

    @Bean
    public AuthenticationFilter authenticationFilter(WebClient.Builder webClientBuilder) {
        return new AuthenticationFilter(webClientBuilder);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder, AuthenticationFilter authenticationFilter) {
        RouteLocatorBuilder.Builder routes = builder.routes();
        for (String serviceName : appContext.getServiceNames()) {
            routes.route(serviceName, r -> r.path("/api/" + serviceName + "/**")
                    .filters(f ->
                            f.filter((exchange, chain) -> {
                                // 指定路径不需要认证
                                String path = exchange.getRequest().getPath().toString();
                                for (String excludePath : appContext.getExcludePaths()) {
                                    if (path.startsWith(excludePath)) {
                                        return chain.filter(exchange);
                                    }
                                }
                                return authenticationFilter.filter(exchange, chain);
                            }).filter((exchange, chain) -> {
                                // 获取原始路径
                                String originalPath = exchange.getRequest().getURI().getRawPath();
                                // 拆分路径段
                                String[] parts = originalPath.split("/");
                                // 构造新的路径，去掉第二段（索引为2，因为 parts[0] 是空字符串）
                                if (parts.length > 2) {
                                    StringBuilder newPath = new StringBuilder();
                                    newPath.append("/").append(parts[1]); // 保留第1段（如 "api"）
                                    for (int i = 3; i < parts.length; i++) {
                                        newPath.append("/").append(parts[i]);
                                    }
                                    // 使用 mutate 创建新的 exchange 请求
                                    ServerHttpRequest newRequest = exchange.getRequest().mutate()
                                            .path(newPath.toString())
                                            .build();
                                    exchange = exchange.mutate().request(newRequest).build();
                                }
                                return chain.filter(exchange);
                            })
                    )
                    .uri("lb://" + serviceName));  // 此处为下游微服务的URI 这里使用 lb:// 前缀来启用负载均衡
        }
        for (String serviceName : appContext.getSocketNames()) {
            routes.route(serviceName, r -> r.path("/" + serviceName + "/**")
                    .filters(f -> f.stripPrefix(1))
                    .uri("lb://" + serviceName));
        }
        return routes.build();
    }
}